package com.p2p.common.redis.impl;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Repository;

import com.p2p.common.base.AbstractBaseRedisDao;
import com.p2p.common.redis.RedisService;
import com.p2p.common.redis.vo.RedisVo;


@Repository("redisService")
public class RedisServiceImpl extends AbstractBaseRedisDao<String, RedisVo> implements RedisService<RedisVo> {

    private Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);

    /**
     * 新增
     * <br>------------------------------<br>
     *
     * @param redisVo
     * @return
     */
    public boolean add(final RedisVo redisVo) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(redisVo.getKey());
                byte[] name = serializer.serialize(redisVo.getValue());
                return connection.setNX(key, name);
            }
        });
        if (redisVo.getValidTime() != null) {
            redisTemplate.expire(redisVo.getKey(), redisVo.getValidTime(), redisVo.getTimeUnit());
        }
        logger.info("添加了redis");
        return result;
    }

    /**
     * 批量新增 使用pipeline方式
     * <br>------------------------------<br>
     *
     * @param list
     * @return
     */
    public boolean add(final List<RedisVo> list) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                for (RedisVo redisVo : list) {
                    byte[] key = serializer.serialize(redisVo.getKey());
                    byte[] name = serializer.serialize(redisVo.getValue());
                    connection.setNX(key, name);
                }
                return true;
            }
        }, false, true);
        return result;
    }

    /**
     * 删除
     * <br>------------------------------<br>
     *
     * @param key
     */
    public void delete(String key) {
        List<String> list = new ArrayList<String>();
        list.add(key);
        delete(list);
    }

    /**
     * 删除多个
     * <br>------------------------------<br>
     *
     * @param keys
     */
    public void delete(List<String> keys) {
        redisTemplate.delete(keys);
    }

    /**
     * 修改
     * <br>------------------------------<br>
     *
     * @param redisVo
     * @return
     */
    public boolean update(final RedisVo redisVo) {
        String key = redisVo.getKey();
//        if (key == null) {  
//            throw new NullPointerException("数据行不存在, key = " + key);  
//        }  
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(redisVo.getKey());
                byte[] name = serializer.serialize(redisVo.getValue());
                connection.set(key, name);
                return true;
            }
        });
        if (redisVo.getValidTime() != null) {
            redisTemplate.expire(redisVo.getKey(), redisVo.getValidTime(), redisVo.getTimeUnit());
        }
        logger.info("更新了redis");
        return result;
    }

    /**
     * 通过key获取
     * <br>------------------------------<br>
     *
     * @param keyId
     * @return
     */
    public RedisVo get(final String keyId) {
        RedisVo result = redisTemplate.execute(new RedisCallback<RedisVo>() {
            public RedisVo doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(keyId);
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                String name = serializer.deserialize(value);
                return new RedisVo(keyId, name);
            }
        });
        return result;
    }
}  